

public class Register {

    private short IR, A, FLAGS, DPH, DPL, SPH, SPL, PCH, PCL, TPH, TPL, MDR;
    private short R0_0, R1_0, R2_0, R3_0;
    private short R0_1, R1_1, R2_1, R3_1;
    //private short R0, R1, R2, R3; 
    private int Bank;
    private int PC, SP, DPTR, TMPA;

    public Register() {
        reset();
    }

    public void reset() {
        Bank = 0;
        IR = A = FLAGS = DPH = DPL = SPH = SPL = PCH = PCL = TPH = TPL = MDR = 0;
        R0_0 = R1_0 = R2_0 = R3_0 = 0;
        R0_1 = R1_1 = R2_1 = R3_1 = 0;
        //R0= R1= R2= R3=0;
    }

    /*public int setBank(int bank) {
    if ((bank == 0) || (bank == 1)) {
    Bank = bank;
    return 1;
    } else {
    return 0;
    }
    }*/
    public int getBank() {
        return Bank;
    }

    public short getIR() {
        return IR;
    }

    public void setIR(int ir) {
        IR = (short) ir;
    }

    public short getA() {
        return A;
    }

    public void setA(int a) {
        A = (short) a;
    }

    public short getFLAGS() {
        return FLAGS;
    }

    public void setFLAGS(int flags) {
        FLAGS = (short) flags;
    }

    public short getDPH() {
        return DPH;
    }

    public void setDPH(int dph) {
        DPH = (short) dph;
    }

    public short getDPL() {
        return DPL;
    }

    public void setDPL(int dpl) {
        DPL = (short) dpl;
    }

    public short getSPH() {
        return SPH;
    }

    public void setSPH(int sph) {
        SPH = (short) sph;
    }

    public short getSPL() {
        return SPL;
    }

    public void setSPL(int spl) {
        SPL = (short) spl;
    }

    public short getPCH() {
        return PCH;
    }

    public void setPCH(int pch) {
        PCH = (short) pch;
    }

    public short getPCL() {
        return PCL;
    }

    public void setPCL(int pcl) {
        PCL = (short) pcl;
    }

    public short getTPH() {
        return TPH;
    }

    public void setTPH(int tph) {
        TPH = (short) tph;
    }

    public short getTPL() {
        return TPL;
    }

    public void setTPL(int tpl) {
        TPL = (short) tpl;
    }

    public short getMDR() {
        return MDR;
    }

    public void setMDR(int mdr) {
        MDR = (short) mdr;
    }

    public short getR0_0() {
        return R0_0;
    }

    public void setR0_0(int r0_0) {
        R0_0 = (short) r0_0;
    }

    public short getR1_0() {
        return R1_0;
    }

    public void setR1_0(int r1_0) {
        R1_0 = (short) r1_0;
    }

    public short getR2_0() {
        return R2_0;
    }

    public void setR2_0(int r2_0) {
        R2_0 = (short) r2_0;
    }

    public short getR3_0() {
        return R3_0;
    }

    public void setR3_0(int r3_0) {
        R3_0 = (short) r3_0;
    }

    public short getR0_1() {
        return R0_1;
    }

    public void setR0_1(int r0_1) {
        R0_1 = (short) r0_1;
    }

    public short getR1_1() {
        return R1_1;
    }

    public void setR1_1(int r1_1) {
        R1_1 = (short) r1_1;
    }

    public short getR2_1() {
        return R2_1;
    }

    public void setR2_1(int r2_1) {
        R2_1 = (short) r2_1;
    }

    public short getR3_1() {
        return R3_1;
    }

    public void setR3_1(int r3_1) {
        R3_1 = (short) r3_1;
    }

    public void setR0(int r0) {
        switch (Bank) {
            case 0:
                R0_0 = (short) r0;
                break;
            case 1:
                R0_1 = (short) r0;
                break;
        }
    }

    public void setR1(int r1) {
        switch (Bank) {
            case 0:
                R1_0 = (short) r1;
                break;
            case 1:
                R1_1 = (short) r1;
                break;
        }
    }

    public void setR2(int r2) {
        switch (Bank) {
            case 0:
                R2_0 = (short) r2;
                break;
            case 1:
                R2_1 = (short) r2;
                break;
        }
    }

    public void setR3(int r3) {
        switch (Bank) {
            case 0:
                R3_0 = (short) r3;
                break;
            case 1:
                R3_1 = (short) r3;
                break;
        }
    }

    public short getR0() {
        switch (Bank) {
            case 0:
                return R0_0;
            case 1:
                return R0_1;
            default:
                return 0;
        }
    }

    public short getR1() {
        switch (Bank) {
            case 0:
                return R1_0;
            case 1:
                return R1_1;
            default:
                return 0;
        }
    }

    public short getR2() {
        switch (Bank) {
            case 0:
                return R2_0;
            case 1:
                return R2_1;
            default:
                return 0;
        }
    }

    public short getR3() {
        switch (Bank) {
            case 0:
                return R3_0;
            case 1:
                return R3_1;
            default:
                return 0;
        }
    }

    public void setPC(int pc) {
        PC = pc;
        PCH = (short) (pc / 256);
        PCL = (short) (pc % 256);
    }

    public int getPC() {
        PC = PCH * 256 + PCL;
        return PC;
    }

    public void setSP(int sp) {
        SP = sp;
        SPH = (short) (sp / 256);
        SPL = (short) (sp % 256);
    }

    public int getSP() {
        SP = SPH * 256 + SPL;
        return SP;
    }

    public void setDPTR(int dptr) {
        DPTR = dptr;
        DPH = (short) (dptr / 256);
        DPL = (short) (dptr % 256);
    }

    public int getDPTR() {
        DPTR = DPH * 256 + DPL;
        return DPTR;
    }

    public void setTMPA(int tmpa) {
        TMPA = tmpa;
        TPH = (short) (tmpa / 256);
        TPL = (short) (tmpa % 256);
    }

    public int getTMPA() {
        TMPA = TPH * 256 + TPL;
        return TMPA;
    }

    public void setC(int c) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        bits[7] = c;
        FLAGS = this.bit2Byte(bits);
    }

    public int getC() {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        return bits[7];
    }

    public void setZ(int z) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        bits[6] = z;
        FLAGS = this.bit2Byte(bits);
    }

    public int getZ() {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        return bits[6];
    }

    public void setAC(int ac) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        bits[5] = ac;
        FLAGS = this.bit2Byte(bits);
    }

    public int getAC() {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        return bits[5];
    }

    public void setP(int p) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        bits[4] = p;
        FLAGS = this.bit2Byte(bits);
    }

    public int getP() {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        return bits[4];
    }

    public void setS(int s) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        bits[3] = s;
        FLAGS = this.bit2Byte(bits);
    }

    public int getS() {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        return bits[3];
    }

    public void setOV(int ov) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        bits[2] = ov;
        FLAGS = this.bit2Byte(bits);
    }

    public int getOV() {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        return bits[2];
    }

    public void setIE(int ie) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        bits[1] = ie;
        FLAGS = this.bit2Byte(bits);
    }

    public int getIE() {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        return bits[1];
    }

    public void setBS(int bs) {
        int[] bits = new int[8];
        bits = this.byte2Bit(FLAGS);
        Bank = bs;
        bits[0] = bs;
        FLAGS = this.bit2Byte(bits);
    }

    public int getBS() {
        return Bank;
    }

    private short bit2Byte(int[] b) {
        short byt = (short) (b[0] * 1 + b[1] * 2 + b[2] * 4 + b[3] * 8 + b[4] * 16 + b[5] * 32 + b[6] * 64 + b[7] * 128);
        return byt;
    }

    private int[] byte2Bit(short b) {
        int[] bits = new int[8];
        bits[7] = b / 128;
        bits[6] = (b % 128) / 64;
        bits[5] = (b % 64) / 32;
        bits[4] = (b % 32) / 16;
        bits[3] = (b % 16) / 8;
        bits[2] = (b % 8) / 4;
        bits[1] = (b % 4) / 2;
        bits[0] = (b % 2) / 1;

        return bits;
    }

    public static void main(String[] args) {

        Register reg = new Register();
        reg.setA(0xff);
        System.out.println(reg.getA());
        reg.setFLAGS((short) 0xff);
        System.out.println(reg.getFLAGS());
        System.out.println(reg.getIE());
        reg.setIE(0);
        System.out.println(reg.getFLAGS());
        System.out.println(reg.getIE());
        System.out.println();
        reg.setPC(0xAAAA);
        System.out.println(reg.getPC());
        System.out.println(reg.getPCH());
        System.out.println(reg.getPCL());
        reg.setPCH((short) 0xff);
        reg.setPCL((short) 0xff);
        System.out.println();
        System.out.println(reg.getPC());
        System.out.println(reg.getPCH());
        System.out.println(reg.getPCL());

        // TODO code application logic here
    }

    /*public void PopPC(){
    SP = SP - 2;
    setSP(SP);
    }*/
    void increasePC() {
        PC++;
        PCH = (short) (PC / 256);
        PCL = (short) (PC % 256);
    }

    void decreasePC() {
        PC--;
        PCH = (short) (PC / 256);
        PCL = (short) (PC % 256);
    }

    void increaseSP() {
        SP++;
        SPH = (short) (SP / 256);
        SPL = (short) (SP % 256);
    }

    void decreaseSP() {
        SP--;
        SPH = (short) (SP / 256);
        SPL = (short) (SP % 256);
    }
}
